--
-- VHDL Architecture Reverb_lib.delay.behaviour
--
-- Created:
--          by - Siebe.UNKNOWN (SIEBJE)
--          at - 13:25:15 20-05-2008
--
-- using Mentor Graphics HDL Designer(TM) 2005.3 (Build 75)
--
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity delay is
    port(
      clk						: in std_logic;
		clk_48k					: in std_logic;
      reset						: in std_logic;
		
		control_in				: in std_logic_vector(7 downto 0);
		control_out				: out std_logic_vector(3 downto 0);
		
      PCM_data_in				: in std_logic_vector(15 downto 0);
		PCM_data_out			: out std_logic_vector(15 downto 0)
      );
  end entity delay;

--
architecture behaviour of delay is
   
  component fifo_32k_16 is
	port (
		clk			: in std_logic;
		din			: in std_logic_VECTOR(15 downto 0);
		rd_en			: in std_logic;
		rst			: in std_logic;
		wr_en			: in std_logic;
		data_count	: out std_logic_VECTOR(14 downto 0);
		dout			: out std_logic_VECTOR(15 downto 0);
		empty			: out std_logic;
		full			: out std_logic
		);
	end component fifo_32k_16;
  
	signal go					: std_logic := '0';
	signal fifo_empty			: std_logic := '0';
	signal fifo_full			: std_logic := '0';
	signal count				: std_logic_vector(15 downto 0) := "0111111111111111";				--initial setting
	signal read_enable		: std_logic := '1';
	signal data_count			: std_logic_vector(14 downto 0);
	signal delay_inter		: std_logic_vector(15 downto 0);
	signal delay_cycles		: std_logic_vector(15 downto 0);
	signal reset_n				: std_logic := '1';
begin
	delay_cycles(14 downto 11) <= control_in(7 downto 4);			--delay cycles range: 0 - 30720 by 2048
	delay_cycles(10 downto 0)	<= (others => '1');					--delay cycles range: 2047 - 32767 by 2048
	delay_cycles(15)				<= '0';

	control_out(0) 			<= fifo_full;
	control_out(1) 			<= fifo_empty;
	control_out(3 downto 2) <= "10";

	reset_n		<= not reset;

	Fifo0: fifo_32k_16 port map(	clk			=> clk_48k,			--FIFO runs on 48kHz clock  
											din			=> PCM_data_in,
											rd_en			=> go,
											rst			=> reset_n,
											wr_en			=> read_enable,
											data_count	=> data_count,
											dout			=> delay_inter,
											empty			=> fifo_empty,
											full			=> fifo_full
										);

	Process0: process (clk_48k, reset)
	begin
		if (reset = '0') then
			PCM_data_out 	<= (others => '0');
			count 			<= "0111111111111111";	--default set maximum value
			go 				<= '0';
			read_enable		<= '0';
		elsif (clk_48k'event and clk_48k = '1') then
			PCM_data_out <= delay_inter;
			read_enable <= '1';
			if count = 0 then
				go <= '1';								--delay == %delay_cycles% samples
			elsif count > delay_cycles then		--set correct delay time with 1 cycle delay
				count <= delay_cycles;
			elsif fifo_full = '0' then				--only decrement if the fifo has space
				count <= count - 1;
			end if;
		end if;
	end process;
    
END ARCHITECTURE behaviour;
